package main

import (
   "fmt"
   core "gorule/core"
   "reflect"
)


type Obj struct {
   name string
}

func visit(list []int, f func(int)) {
   for _, v := range list {
      f(v)
   }
}

type human struct {
   name string
   sex bool
   age int
}

type student struct {
   *human //指针匿名组合
   id int
   score int
}

func (h *human) say() string {
   // 这里的方法如果定义为 *human 则方法执行后 h 的变量本身的值会被改掉
   h.name = "human"
   return fmt.Sprintf("I am a human my name is %s.",h.name)
}

//func (s *student) say() string {
//   s.name = "student"
//   return fmt.Sprintf("I am a student my name is %s. my score is %d", s.name, s.score)
//}

func printMap(m map[string]interface{}) {
   for k, v := range m {
      switch value := v.(type) {
      case nil:
         fmt.Println(k, "is nil", "null")
      case string:
         fmt.Println(k, "is string", value)
      case int:
         fmt.Println(k, "is int", value)
      case float64:
         fmt.Println(k, "is float64", value)
      case []interface{}:
         fmt.Println(k, "is an array:")
         for i, u := range value {
            fmt.Println(i, u)
         }
      case map[string]interface{}:
         fmt.Println(k, "is an map:")
         printMap(value)
      default:
         fmt.Println(k, "is unknown type", fmt.Sprintf("%T", v))
      }
   }
}

func main() {
   fmt.Println("Hello, World!")

   // 切片
   l := make([]string, 2)
   l[0] = "a"
   l[1] = "b"
   l = append(l, "c")
   fmt.Println(l)

   // 结构体
   var obj = &Obj{"niyoufa"}
   fmt.Println(obj.name)

   // 匿名函数
   fmt.Println(func(i int, j int) int{
      return i + j
   }(1, 2))

   f := func(i int, j int) int {
      return i + j
   }
   fmt.Println(f(1, 2))

   visit([]int{1, 2, 3, 4}, func(v int) {
      fmt.Println(v)
   })

   // 结构体-继承
   h := human{
      name: "niyoufa",
      sex:  false,
      age: 20,
   }
   s := student{
      human: &h,
      id: 0,
      score: 10,
   }
   fmt.Println(h.say())
   fmt.Println(s.say())
   fmt.Println(s.human.say())
   fmt.Println(s.name)

   m := make(map[string]interface{})
   var i interface{} = "niyoufa"
   m["a"] = i
   m["b"] = "b"
   m["c"] = false
   fmt.Println(m)
   fmt.Println(reflect.TypeOf(m["a"]))
   printMap(m)

   fmt.Println(reflect.TypeOf(m["a"]))
   fmt.Println(reflect.TypeOf(m["c"]))

   var param interface{}
   param = core.NewContext()
   switch param.(type) {
   case core.Context:
      fmt.Println("core.Context")
   }

   str := "测试"
   for _, s := range str{
      fmt.Println(string(s))
   }
   fmt.Println(string(str[0:3]))

}